﻿using SketchUpAPI.NET.Enums;
using SketchUpAPI.NET.SketchUp.Exception;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection.Emit;
using System.Runtime.InteropServices;
using System.Runtime.Remoting.Messaging;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;

namespace SketchUpAPI.NET.Objects
{
    /// <summary>
    /// 图层文件夹
    /// </summary>
    /// <remarks>对 SketchUpAPI 中的 SULayerFolderRef 的包装</remarks>
    public class LayerFolder : ObjectBase
    {
        #region API 函数
        /// <summary>
        /// 创建图层文件夹
        /// </summary>
        /// <param name="layer_folder"></param>
        /// <param name="name">名字不需要唯一，但不能为空</param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SULayerFolderCreate(out IntPtr layer_folder, [MarshalAs(UnmanagedType.LPUTF8Str)] string name);

        /// <summary>
        /// 释放资源
        /// </summary>
        /// <param name="layer_folder"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SULayerFolderRelease(ref IntPtr layer_folder);

        /// <summary>
        /// 获取图层文件夹的名字
        /// </summary>
        /// <param name="layer_folder"></param>
        /// <param name="name"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SULayerFolderGetName(IntPtr layer_folder, ref IntPtr name);

        /// <summary>
        /// 设置图层文件夹的名字
        /// </summary>
        /// <param name="layer_folder"></param>
        /// <param name="name"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SULayerFolderSetName(IntPtr layer_folder, [MarshalAs(UnmanagedType.LPUTF8Str)] string name);

        /// <summary>
        /// 获取是否可见
        /// </summary>
        /// <param name="layer_folder"></param>
        /// <param name="visible"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SULayerFolderGetVisibility(IntPtr layer_folder, out bool visible);

        /// <summary>
        /// 设置是否可见
        /// </summary>
        /// <param name="layer_folder"></param>
        /// <param name="visible"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SULayerFolderSetVisibility(IntPtr layer_folder, bool visible);

        /// <summary>
        /// 获取是否在新场景中可见
        /// </summary>
        /// <param name="layer_folder"></param>
        /// <param name="visible"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SULayerGroupGetVisibleOnNewScenes(IntPtr layer_folder, out bool visible);

        /// <summary>
        /// 设置是否在新场景中可见
        /// </summary>
        /// <param name="layer_folder"></param>
        /// <param name="visible"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SULayerGroupSetVisibleOnNewScenes(IntPtr layer_folder, bool visible);

        /// <summary>
        /// 添加图层
        /// </summary>
        /// <param name="layer_folder"></param>
        /// <param name="layer"><see cref="Objects.Layer"/></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SULayerFolderAddLayer(IntPtr layer_folder, IntPtr layer);

        /// <summary>
        /// 移除图层
        /// </summary>
        /// <param name="layer_folder"></param>
        /// <param name="layer"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SULayerFolderRemoveLayer(IntPtr layer_folder, IntPtr layer);

        /// <summary>
        /// 获取图层个数
        /// </summary>
        /// <param name="layer_folder"></param>
        /// <param name="count"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SULayerFolderGetNumLayers(IntPtr layer_folder, out int count);

        /// <summary>
        /// 获取全部图层
        /// </summary>
        /// <param name="layer_folder"></param>
        /// <param name="len"></param>
        /// <param name="layers"></param>
        /// <param name="realcount"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SULayerFolderGetLayers(IntPtr layer_folder, int len, IntPtr[] layers, out int realcount);

        /// <summary>
        /// 添加图层文件夹
        /// </summary>
        /// <param name="layer_folder"></param>
        /// <param name="add_folder"><see cref="Objects.LayerFolder"/></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SULayerFolderAddLayerFolder(IntPtr layer_folder, IntPtr add_folder);

        /// <summary>
        /// 获取图层文件夹个数
        /// </summary>
        /// <param name="layer_folder"></param>
        /// <param name="count"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SULayerFolderGetNumLayerFolders(IntPtr layer_folder, out int count);

        /// <summary>
        /// 获取全部图层文件夹
        /// </summary>
        /// <param name="layer_folder"></param>
        /// <param name="len"></param>
        /// <param name="layer_folders"><see cref="Objects.LayerFolder"/></param>
        /// <param name="realcount"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SULayerFolderGetLayerFolders(IntPtr layer_folder, int len, IntPtr[] layer_folders, out int realcount);

        /// <summary>
        /// 父级图层文件夹
        /// </summary>
        /// <param name="layer_folder"></param>
        /// <param name="parent"><see cref="Objects.LayerFolder"/></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SULayerFolderGetParentLayerFolder(IntPtr layer_folder, out IntPtr parent);
        #endregion

        /// <summary>
        /// 图层文件夹名字
        /// </summary>
        public string Name
        {
            get
            {
                StringRef s = StringRef.Empty;
                SketchUpExceptionHelper.ThrowSUResult(SULayerFolderGetName(Id, ref s.Id));
                return s.Dispose();
            }
            set
            {
                SketchUpExceptionHelper.ThrowSUResult(SULayerFolderSetName(Id, value));
            }
        }

        /// <summary>
        /// 是否可见
        /// </summary>
        public bool Visibility
        {
            get
            {
                SketchUpExceptionHelper.ThrowSUResult(SULayerFolderGetVisibility(Id, out bool v));
                return v;
            }
            set
            {
                SketchUpExceptionHelper.ThrowSUResult(SULayerFolderSetVisibility(Id, value));
            }
        }

        /// <summary>
        /// 是否在新场景中可见
        /// </summary>
        public bool VisibleOnNewScenes
        {
            get
            {
                SketchUpExceptionHelper.ThrowSUResult(SULayerGroupGetVisibleOnNewScenes(Id, out bool v));
                return v;
            }
            set
            {
                SketchUpExceptionHelper.ThrowSUResult(SULayerGroupSetVisibleOnNewScenes(Id, value));
            }
        }

        /// <summary>
        /// 所有图层
        /// </summary>
        public List<Layer> Layers
        {
            get
            {
                SketchUpExceptionHelper.ThrowSUResult(SULayerFolderGetNumLayers(Id, out int c));
                IntPtr[] pts = new IntPtr[c];
                SketchUpExceptionHelper.ThrowSUResult(SULayerFolderGetLayers(Id, c, pts, out _));
                return pts.Select(i => new Layer(i)).ToList();
            }
        }

        /// <summary>
        /// 获取全部图层文件夹
        /// </summary>
        public List<LayerFolder> LayerFolders
        {
            get
            {
                SketchUpExceptionHelper.ThrowSUResult(SULayerFolderGetNumLayerFolders(Id, out int c));
                IntPtr[] pts = new IntPtr[c];
                SketchUpExceptionHelper.ThrowSUResult(SULayerFolderGetLayerFolders(Id, c, pts, out _));
                return pts.Select(i => new LayerFolder(i)).ToList();
            }
        }

        /// <summary>
        /// 父级图层文件夹
        /// </summary>
        public LayerFolder Parent
        {
            get
            {
                SketchUpExceptionHelper.ThrowSUResult(SULayerFolderGetParentLayerFolder(Id, out IntPtr p));
                return new LayerFolder(p);
            }
        }

        public LayerFolder(string name)
        {
            SketchUpExceptionHelper.ThrowSUResult(SULayerFolderCreate(out Id, name));
        }

        internal LayerFolder(IntPtr id) => Id = id;

        /// <summary>
        /// 添加图层
        /// </summary>
        /// <param name="layer"></param>
        public void Add(Layer layer)
        {
            SketchUpExceptionHelper.ThrowSUResult(SULayerFolderAddLayer(Id, layer.Id));
        }

        /// <summary>
        /// 添加图层文件夹
        /// </summary>
        /// <param name="folder"></param>
        public void Add(LayerFolder folder)
        {
            SketchUpExceptionHelper.ThrowSUResult(SULayerFolderAddLayerFolder(Id, folder.Id));
        }

        /// <summary>
        /// 移除图层
        /// </summary>
        /// <param name="layer"></param>
        public void Remove(Layer layer)
        {
            SketchUpExceptionHelper.ThrowSUResult(SULayerFolderRemoveLayer(Id, layer.Id));
        }

        public override void Dispose()
        {
            SketchUpExceptionHelper.ThrowSUResult(SULayerFolderRelease(ref Id));
        }
    }
}